● Excel2010・2000でのピボットテーブルのワンクリック自動作成 ~ 現在の表に自動的に名前の定義をして、「ソースの表として行と列が増減しても範囲の再設定が不要にした状態」での、ピボットのワンクリック自動作成
※間違ってたらすみません。
※メモ書きなので、自分でも意味不明な箇所も多いです。ごめんなさい。
※一番最後のが一番使いやすいかも?関数化されているので。
★ ピボット作成の複数回数の自動化を関数化したもの(2010以降用)
目次
★ はじめに
★ Excel2010用のピボット自動作成(ソース表の行列増減可変)のコード
★ Excel2000用のピボット自動作成(ソース表の行列増減可変)のコード
※Shift+TABキー、もしくは、Homeキー、Homeキー+TAB数回、を押すと、目次付近に戻れます。
★ はじめに
今目の前にある表から、ワンクリックでピボットテーブルの作成ができると大変便利です。
本記事ではそれを可能にするプログラムをご紹介させて頂きたいと思います。
(ピボットが広まらない大きな理由のひとつに、「よくわからない・作るのが面倒」ということがあると思いますのでその解決としてもご利用してほしいと願います。初心者の方ほど、この記事を誰かに読んでもらって、処置してほしいと思います。)
本記事の例では、一応、「今見ている表」が、1シートに1つの表で、かつ、A1セルから横がすべて列名で埋まっている、かつ、空白行・空白列も無い、セル結合も無い、という表に限っています。それでないとプログラムが正常に動きません。
表が「A2セルやB2、B4、C3、・・・・」などから始まっている、つまり、表の上や左に空白行や空白列があるケースは想定していません。
後述のVBAプログラムのコードをPersonal.xlsやxlsbの標準モジュールにコピペして、リボン(またはクイックアクセスツールバーなど)にメニューボタン化します。
そうすると、今見ている表から、「ソースの表の行や列が増減しても範囲の再設定が必要が無いピボットテーブル」がワンクリックで作れるようになります。もちろん、ソースの表がMicrosoft Query(SQL)の抽出結果の表であってもOKです。
メニューボタン化する方法は、「excel クイックアクセスツールバー マクロ 登録」などでGoogle検索してみてください。(リボンへのメニューボタン化・関連の記事5つ→1、2、3、4、5。または巻末のリンクで。)
(「Personal.xlsやxlsb」とは、『すべてのExcelファイルで使える共用機能を作るための特殊なExcelファイル』のことです。)
※なお、このコードをリボン(またはクイックアクセスツールバーなど)にメニューボタン化していない場合は、例えばExcel2010の場合なら、開発タブ→マクロ→PERSONAL.XLS!Excel2010_MakePvt01(あるいはPERSONAL.XLS!Excel2k_MakePvt01)などで実行できます。
このコードは、ピボットのソースにしたいシートを開いておき、(一応念のために、)その中のどこでもいいのでどれか1つのセルをクリックしてから実行します。
さささっと(集計による)調べ物をしたいときに便利ですし、無駄な関数やVBAを減らすことにも多少なりとも貢献できると思います。
もちろん、ピボットのソースの表を「=OFFSET($A$1,0,0,COUNTA($A:$A),COUNTA($1:$1))」を使って名前の定義をしておきますので、ピボットのソースの表の側で列や行が増減しても、その範囲の再設定は必要ありません。
(逆に言うと、このピボットを作ったのちに、ソースの表の内容を全く別のものに入れ替えてピボットを更新すれば、フィールドリストの内容も新しいソースの内容が反映されます。)
集計だけでなく、「重複調査」「濁音・破裂音・フリガナの音読み訓読み、スペース、その他の入力ミスの調査」「簡易アンケート調査」等々をしたい時にもさっとやれるので便利です。
なお、名前の定義のときの名前を自由に設定したかったり、さらに新しいシートにどんどんと新しいピボットを作りたい時、あるいは、ピボットを新しいシートではなくて現在のシートに作りたい場合などは、少し作り変えが必要です。でもその部分は「VBAでのピボット作成」のことを知らなくてもでき、特に困難ではありません。なので、もしご自分でできなかったら、ExcelVBAのできる人に作り変えてもらってください。すぐにやってもらえると思います。
(※ちなみにですが、すでに同名の「名前の定義設定」があったとしても、繰り返し実行しても、名前の定義の行ではエラーになりません。同じシート名の新しいシートを作ろうとした行ではエラーになりますけど…。でもそれも、事前に既存のシート名をチェックして、新しいシートではそれ以外のシート名を付けるようにすればOKです。)
2010でとりあえず動きましたが、いつか2000でもテストしてみます。
(2000の場合は、最後の5行はエラーになるかもしれないので、コメントアウトしておいてから試してみます。)
→2018/06/18:テストしてみた結果、ダメでした。2010用のコードのあとに、2000用のコードを追加しておきます。
★ Excel2010用のピボット自動作成(ソース表の行列増減可変)のコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
' ' Sub Excel2010_MakePvt01() Dim ObjCache As PivotCache Dim ObjTable As PivotTable Dim StrActvShtName As String '現在のシート(アクティブなシート)の行と列が増えてもピボットソースの再設定をしなくても '済むようにする処置。 '具体的には、「名前の定義」の機能にて、 '範囲の設定に「=OFFSET($A$1,0,0,COUNTA($A:$A),COUNTA($1:$1))」を使って、 'ソースとなる表に、自動生成した(名前範囲の)名前を付けます。 '(ピボットのソース範囲の指定には、この「pvtsrc01」という名前を使います。) ' ActiveWorkbook.Names.Add Name:="pvtsrc01", RefersToR1C1:= _ ' "=OFFSET(データセット1!R1C1,0,0,COUNTA(データセット1!C1),COUNTA(データセット1!R1))" StrActvShtName = ActiveSheet.Name ActiveWorkbook.Names.Add Name:="pvtsrc01", RefersToR1C1:= _ "=OFFSET(" & StrActvShtName & "!R1C1,0,0,COUNTA(" & StrActvShtName & "!C1),COUNTA(" & StrActvShtName & "!R1))" ActiveWorkbook.Names("pvtsrc01").Comment = "" 'ピボットキャッシュの作成(名前の定義をした「pvtsrc01」をソースにして。) ' Set ObjCache = ActiveWorkbook.PivotCaches.Create _ ' (SourceType:=xlDatabase, SourceData:=Range("A1").CurrentRegion) Set ObjCache = ActiveWorkbook.PivotCaches.Create _ (SourceType:=xlDatabase, SourceData:="pvtsrc01") '新しいシートの作成 Worksheets.Add '新しいシートの作成 ActiveSheet.Name = "Pvt01" 'そのシートの名前を「Pvt01」にする '新しいシートへの空のピボットテーブルの作成 Set ObjTable = ObjCache.CreatePivotTable _ (tabledestination:=Worksheets("Pvt01").Range("A3"), TableName:="test01Pivot") '古いタイプのピボットの表示・操作性への切り替え '(古いタイプでなくても良ければここは5行全部をコメントアウトします) Worksheets("Pvt01").Range("A3").Select '新しく作ったピボットの任意のセルを選択 With ActiveSheet.PivotTables("test01Pivot") .HasAutoFormat = False .InGridDropZones = True .RowAxisLayout xlTabularRow End With ' '★★ 行ラベルを設定して、集計したい列で集計する ' ' (実際に使いたいときはこの部分をコメントアウトして試してみてください。) ' ObjTable.AddFields RowFields:=Array("行見出しにしたいアイテムのある列名") ' ' ↑ 行ラベルの設定(1つだけの場合。2段、3段、なら、多分だけど、Array("1段目の列名","2段目の列名","3段目の列名")でやる。Columnも同じだと思う。多分。) ' ObjTable.AddDataField ObjTable.PivotFields("数値合計したい列名"), "合計結果" ' ' ↑ 「合計結果」という名前で集計する End Sub ' ' |
★ Excel2000用のピボット自動作成(ソース表の行列増減可変)のコード
(→逆にこちらは2010でも動きます。当方では動きました。xls・xlsm両方とも)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
' ' Sub Excel2k_MakePvt01() Dim ObjCache As PivotCache Dim ObjTable As PivotTable Dim StrActvShtName As String '現在のシート(アクティブなシート)の行と列が増えてもピボットソースの再設定をしなくても '済むようにする処置。 '具体的には、「名前の定義」の機能にて、 '範囲の設定に「=OFFSET($A$1,0,0,COUNTA($A:$A),COUNTA($1:$1))」を使って、 'ソースとなる表に「pvtsrc01」という名前を付けます。 '(ピボットのソース範囲の指定には、この「pvtsrc01」という名前を使います。) StrActvShtName = ActiveSheet.Name ActiveWorkbook.Names.Add Name:="pvtsrc01", RefersToR1C1:= _ "=OFFSET(" & StrActvShtName & "!R1C1,0,0,COUNTA(" & StrActvShtName & "!C1),COUNTA(" & StrActvShtName & "!R1))" 'ActiveWorkbook.Names("pvtsrc01").Comment = "" '新しいシートの作成 Worksheets.Add '新しいシートの作成 ActiveSheet.Name = "Pvt01" 'そのシートの名前を「Pvt01」にする ' '新しいシートへの空のピボットテーブルの作成 ActiveWorkbook.PivotCaches.Add(SourceType:=xlDatabase, _ SourceData:="pvtsrc01").CreatePivotTable _ TableDestination:="Pvt01!R3C1", _ TableName:="aaa" ActiveSheet.PivotTables("aaa").SmallGrid = False '「ここに・・・うんぬん」を表示 ' '★★ ピボットテーブルで行や列を設定して集計をする例。 ' ' (実際に使いたいときは以降の部分をコメントアウトして試してみてください。) ' '以下の例は、ソースの表に「顧客ID」「氏名」「住所01」「単価」「数量」という列がある場合。 ' ' '作ったピボットテーブルをオブジェクト変数に代入。 ' Set ObjTable = ActiveSheet.PivotTables("aaa") ' ' '「顧客ID」列を、1段目の行ラベルに設定。 ' With ObjTable.PivotFields("顧客ID") ' .Orientation = xlRowField ' .Position = 1 ' End With ' ' '「氏名」列を、2段目の行ラベルに設定。 ' With ObjTable.PivotFields("氏名") ' .Orientation = xlRowField ' .Position = 2 ' End With ' ' '「住所01」列を、1段目の列ラベルに設定。 ' With ObjTable.PivotFields("住所01") ' .Orientation = xlColumnField ' .Position = 1 ' End With ' ' '「単価」列を、1段目の集計フィールドに設定。 ' With ObjTable.PivotFields("単価") ' .Orientation = xlDataField ' .Position = 1 ' End With ' ' '「数量」列を、2段目の集計フィールドに設定。 ' With ObjTable.PivotFields("数量") ' .Orientation = xlDataField ' .Position = 2 ' End With End Sub ' ' |
★ 2020/06/16 追記:ピボットと名前範囲の名前がダブらないように自動生成するバージョンを作りました。(ただし、2010用です。2013以降も大丈夫な気がします。ダメだったらごめんなさい!2003以前もダメだと思います。)
前述のバージョンは、1つのピボットを作るだけで終わっていました。
2回目の操作で、「すでにその名前はある」みたいなエラーになってしまいます。
なので、そうならないものを作りました。
こちらのものは、同じソースから、複数のピボットを、自動的に名前を変えて(生成して)、それぞれ、自動作成してくれます。
つまり、何度でもボタンを押すと、押した分だけ、エラー無く、ピボットが自動作成できます。
(ただし、リスト形式でない表をソースにするとこれまでと同様、エラーになります。ご自分でもエラーの回避のコードを追加してみて下さい)
※注意!!・・・ピボットの場合はMicrosoftQueryの場合と違って、作成されたピボットを削除しても、ソースの「名前定義」は削除されません。なので、そのまま利用できますが、ただ、不要になった場合が手動で消す必要があります。
以下、ピボットの連続自動作成が可能なコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
' ' Option Explicit Sub Off2010MakePvt02_AutoName() Dim i_Ans01 As Integer Dim i_PvtCnt01 As Integer Dim ObjCache As PivotCache Dim ObjTable As PivotTable Dim StrActvShtName As String Dim s_2Name As Variant Dim s_WsName001 As String Dim s_NmRngName001 As String 'チェック01 '現在アクティブなシートに すでにピボットがあったら中止。 '「ソースの表じゃないこと」でもエラーになってしまうので。 i_PvtCnt01 = ActiveWorkbook.ActiveSheet.PivotTables.Count 'ピボットの数を数える。 If i_PvtCnt01 = 0 Then 'ピボットの数がゼロなら、 '何もせずに次へ ElseIf i_PvtCnt01 = 1 Then 'ピボットの数が1つ以上なら、 MsgBox "すでにピボットテーブルが作成されています。" & _ vbCrLf & vbCrLf & _ "ソースとなる動的な表(リスト形式の表)を選択してから再操作してください。" Exit Sub End If 'チェック02 '「ソースがリスト形式の表じゃないこと」でエラーになってしまうので、 'それをチェック・回避。 i_Ans01 = MsgBox("本当に目的の動的な表(リスト形式の表)を選択した状態ですか?", vbYesNo) If i_Ans01 = vbOK Then '「はい」が押されたら、 '何もせずに次へ ElseIf i_Ans01 = vbNo Then '「いいえ」が押されたら、 MsgBox "ソースとなる動的な表(リスト形式の表)を選択してから再操作してください。" Exit Sub End If 'ピボットテーブルと、名前範囲の、それぞれの名前の自動設定。 s_2Name = WsNmAndNmRngNmAutoMake 'それぞれの新しい名前を「WsNmAndNmRngNmAutoMake」という自作関数によって自動生成し、配列として受け取る。 s_WsName001 = s_2Name(0) 'シート名を決定 s_NmRngName001 = s_2Name(1) '名前範囲の名前を決定 '現在のシート(アクティブなシート)の行と列が増えても 'ピボットの再設定をしなくても済むようにする処置 '「=OFFSET($A$1,0,0,COUNTA($A:$A),COUNTA($1:$1))」にて '名前の定義の操作をして、ソースとなる表に「pvtsrc01」という名前を付けます。 ' ActiveWorkbook.Names.Add Name:=s_NmRngName001, RefersToR1C1:= _ ' "=OFFSET(データセット1!R1C1,0,0,COUNTA(データセット1!C1),COUNTA(データセット1!R1))" StrActvShtName = ActiveSheet.Name ActiveWorkbook.Names.Add Name:=s_NmRngName001, RefersToR1C1:= _ "=OFFSET(" & StrActvShtName & "!R1C1,0,0,COUNTA(" & StrActvShtName & "!C1),COUNTA(" & StrActvShtName & "!R1))" ActiveWorkbook.Names(s_NmRngName001).Comment = "" 'ピボットキャッシュの作成(名前の定義をした「pvtsrc01」をソースにして。) ' Set ObjCache = ActiveWorkbook.PivotCaches.Create _ ' (SourceType:=xlDatabase, SourceData:=Range("A1").CurrentRegion) Set ObjCache = ActiveWorkbook.PivotCaches.Create _ (SourceType:=xlDatabase, SourceData:=s_NmRngName001) '新しいシートの作成 Worksheets.Add '新しいシートの作成 ActiveSheet.Name = s_WsName001 'そのシートの名前を自動決定されたものにする '新しいシートへの空のピボットテーブルの作成 Set ObjTable = ObjCache.CreatePivotTable _ (TableDestination:=Worksheets(s_WsName001).Range("A3"), TableName:=s_WsName001 & "Pivot") '古いタイプのピボットの表示・操作性への切り替え '(古いタイプでなくても良ければここは5行全部をコメントアウトします) Worksheets(s_WsName001).Range("A3").Select '新しく作ったピボットの任意のセルを選択 With ActiveSheet.PivotTables(s_WsName001 & "Pivot") .HasAutoFormat = False .InGridDropZones = True .RowAxisLayout xlTabularRow End With End Sub '########################################################## 'ピボットテーブルのソースの名前範囲の名前と、 'ピボットを生成する新しいシートの名前を自動生成する関数。 '戻り値を配列で返しているので、呼び出し元でも配列で受ける。 '戻り値は、 'WsNmAndNmRngNmAutoMake(0)がシート名で 'WsNmAndNmRngNmAutoMake(1)が名前範囲の名前になっています。 '########################################################## Function WsNmAndNmRngNmAutoMake() As Variant Dim i As Integer Dim Answ01 As Boolean Dim s_WsNm00 As String Dim s_NmRngNm00 As String '★ 設定部 Answ01 = False i = 1 '★ 実動部 Do Until Answ01 = True '名前の自動生成をするループ。新規の名前が決定するまでループします。 s_WsNm00 = "Pvt" & Format(i, "00") s_NmRngNm00 = "Pvt" & Format(i, "00") & "RngSrc" If WsNmChk01(s_WsNm00) = False Then If NmRngNmChk01(s_NmRngNm00) = False Then Answ01 = True Else End If Else End If i = i + 1 Loop '戻り値にそれぞれの名前をセット。 WsNmAndNmRngNmAutoMake = Array(s_WsNm00, s_NmRngNm00) ' Debug.Print s_WsNm00 ' Debug.Print s_NmRngNm00 ' End Function '################################################################### '指定した名前のワークシートが存在するかどうかのチェックの関数 '存在すればTrueを返し、存在しなければFalseを返します。 'ループを使わない方法=エラーで判別する方法、でやっています。 '################################################################### Function WsNmChk01(s_WsNm01 As String) As Boolean Dim o_Wb02 As Workbook Dim o_Ws02 As Worksheet Set o_Wb02 = ActiveWorkbook On Error Resume Next Set o_Ws02 = o_Wb02.Worksheets(s_WsNm01) '↑存在確認したい「名前範囲」を指定 On Error GoTo 0 If o_Ws02 Is Nothing Then 'Nothingならシートが存在しない '同じ名前のシートが存在しないなら、Falseを返す。 WsNmChk01 = False ElseIf Not o_Ws02 Is Nothing Then '存在したら、Trueを返す。 WsNmChk01 = True End If End Function '################################################################### '指定した名前の名前範囲が存在するかどうかのチェックの関数 '存在すればTrueを返し、存在しなければFalseを返します。 'ループを使わない方法=エラーで判別する方法、でやっています。 '################################################################### Function NmRngNmChk01(s_NmRng01 As String) As Boolean Dim o_Wb03 As Workbook Dim o_Name As Name Set o_Wb03 = ActiveWorkbook On Error Resume Next Set o_Name = o_Wb03.Names(s_NmRng01) '↑存在確認したい「名前範囲」を指定 On Error GoTo 0 If o_Name Is Nothing Then 'Nothingならシートが存在しない '同じ名前のシートが存在しないなら、Falseを返す。 NmRngNmChk01 = False ElseIf Not o_Name Is Nothing Then '存在したら、Trueを返す。 NmRngNmChk01 = True End If End Function 'テストサンプル Function NmChkTest01() Dim s_WsNm As String Dim o_Wb As Workbook Dim o_Ws As Worksheet Dim i As Integer Set o_Wb = ThisWorkbook i = 1 On Error Resume Next s_WsNm = "Pvt" & Format(i, "000") Set o_Ws = o_Wb.Worksheets(s_WsNm) '←存在確認したいシートを指定 On Error GoTo 0 If o_Ws Is Nothing Then 'Nothingならシートが存在しない '同じ名前のシートが存在しないなら、何もしない。 ElseIf Not o_Ws Is Nothing Then 'Nothingならシートが存在しない '存在したら、番号を1つ繰り上げる s_WsNm = "Pvt" & Format(i + 1, "000") End If End Function ' ' |
※メニュー関連の記事
Excel2010のリボンに、Excel2000と同じプログラムコードのコピペでユーザー設定ボタンを生成する。(一応ツールバー単位で)
ExcelVBA:WordVBA:他のVBA:ビジネス基礎:VBAプログラム(マクロ)をクイックツールバーにボタンとして組み込む方法
Word2010のリボンに、Word2000と同じプログラムコードのコピペでユーザー設定ボタンを生成する。(一応ツールバー単位で)
Excel2010のリボンに、Excel2000と同じプログラムコードのコピペでユーザー設定ボタンを生成する~02。(一応ツールバー単位で。ピボットテーブル一発作成ボタン等も追加。ドロップダウンでの階層化ボタンも追加。)
★ ピボット作成の複数回数の自動化を関数化したもの(2010以降用)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
' ' '################################################################################# '指定した名前で、自動で「名前定義+行列増減自動化+ピボット作成」をする関数 ' '呼び出し例 'Call Excel2010_MakePvt02(Thisworkbook,"Pvtソース","RngNm_Pvtソース01","新規PVT") ' ' ' '引数「o_WBNm05」はピボット作成する先のブックの名前 '例:o_WBNm05 → ThisWorkbook、ActiveWorkbook、など。 ' ' '引数「s_PvtSrcWSNm05」はピボットのソースとなるシートの名前 '例:s_PvtSrcWSNm05 → "Pvtソース" ' ' '引数「s_RngTeigiNm01」はセル範囲の名前定義したいときの名前。 ' 接頭語として「Name_」や「RngNm_」などを付けるとわかりやすいかも。 ' 名前定義は、同じ名前定義を指定すると、エラーではなく ' 上書きっぽくなるみたい。なのでいちいち「削除→新規生成」はしない。 '例:s_RngTeigiNm01 → "Name_Pvtソース01" '例:s_RngTeigiNm01 → "RngNm_Pvtソース01" ' ' '引数「s_PvtDistWsBaseNm」はピボットを生成する先のシートの名前。 ' 基本、ピボットを毎回新規シートに作る仕様にしたので。 ' 古いピボットシートは残り、新しいものは接尾語に、秒単位までの時刻が付く。 '例:s_PvtDistWsBaseNm → "新規PVT" '################################################################################# Function Excel2010_MakePvt02(o_WBNm05 As Workbook, _ s_PvtSrcWSNm05 As String, _ s_RngTeigiNm01 As String, _ s_PvtDistWsBaseNm As String) Dim o_Cache As PivotCache Dim o_PvtTable As PivotTable Dim s_ActvShtName As String Dim o_PvtNewWS As Worksheet Dim s_NewPvtShtNm As String Dim o_NewPvtWs As Worksheet '現在のシート(アクティブなシート)の行と列が増えてもピボットソースの再設定をしなくても '済むようにする処置。 '具体的には、「名前の定義」の機能にて、 '範囲の設定に「=OFFSET($A$1,0,0,COUNTA($A:$A),COUNTA($1:$1))」を使って、 'ソースとなる表に、自動生成した(名前範囲の)名前を付けます。 '(ピボットのソース範囲の指定には、この「pvtsrc01」という名前を使います。) ' ※同じ名前&式内容の名前定義があっても(つまり上書きのような感じになっても) ' エラーにならないようなので、名前定義を分岐して消し込んだりしないことにした。 ' つまり、名前定義の「削除→新規生成」はしない。 ' ActiveWorkbook.Names.Add Name:="Name_Pvtソース01", RefersToR1C1:= _ ' "=OFFSET(データセット1!R1C1,0,0,COUNTA(データセット1!C1),COUNTA(データセット1!R1))" ' s_ActvShtName = ActiveSheet.Name ' s_ActvShtName = Worksheets("Pvtソース").Name s_ActvShtName = Worksheets.Item(s_PvtSrcWSNm05).Name ' ActiveWorkbook.Names.Add Name:="Name_Pvtソース01", RefersToR1C1:= _ "=OFFSET(" & s_ActvShtName & "!R1C1,0,0,COUNTA(" & s_ActvShtName & "!C1),COUNTA(" & s_ActvShtName & "!R1))" ' ActiveWorkbook.Names("Name_Pvtソース01").Comment = "" o_WBNm05.Names.Add Name:=s_RngTeigiNm01, RefersToR1C1:= _ "=OFFSET(" & s_ActvShtName & "!R1C1,0,0,COUNTA(" & s_ActvShtName & "!C1),COUNTA(" & s_ActvShtName & "!R1))" o_WBNm05.Names.Item(s_RngTeigiNm01).Comment = "" 'ピボットキャッシュの作成(名前の定義をした「pvtsrc01」をソースにして。) ' Set o_Cache = ActiveWorkbook.PivotCaches.Create _ ' (SourceType:=xlDatabase, SourceData:=Range("A1").CurrentRegion) Set o_Cache = o_WBNm05.PivotCaches.Create _ (SourceType:=xlDatabase, SourceData:=s_RngTeigiNm01) '新しいシートの作成 Worksheets.Add '新しいシートの作成 ' ActiveSheet.Name = "新規PVT" 'そのシートの名前を「Pvtソース」にする ' 'すでに同じ名前のピボットのシートがあるかのチェック。 ' 'あれば、別の名前を生成する。(ここでは時刻を付加した名前で。) ' If SheetExistChk("新規PVT") Then If SheetExistChk(s_PvtDistWsBaseNm) Then ' Application.DisplayAlerts = False ' Worksheets("新規PVT").Delete ' Application.DisplayAlerts = True s_NewPvtShtNm = s_PvtDistWsBaseNm & Replace(Time(), ":", "", , , vbBinaryCompare) Else s_NewPvtShtNm = s_PvtDistWsBaseNm End If ActiveSheet.Name = s_NewPvtShtNm '生成された新しいシートの名前を今生成した名前にする Set o_NewPvtWs = Worksheets.Item(s_NewPvtShtNm) '新しいシートへの空のピボットテーブルの作成 Set o_PvtTable = o_Cache.CreatePivotTable _ (tabledestination:=o_NewPvtWs.Range("A3"), TableName:=s_RngTeigiNm01) '古いタイプのピボットの表示・操作性への切り替え '(古いタイプでなくても良ければここは5行全部をコメントアウトします) o_NewPvtWs.Range("A3").Select '新しく作ったピボットの任意のセルを選択 ' With Worksheets.Item(s_NewPVTShtNm).PivotTables.Item(s_RngTeigiNm01) With o_PvtTable .HasAutoFormat = False .InGridDropZones = True .RowAxisLayout xlTabularRow End With ' '★★ 行ラベルを設定して、集計したい列で集計する ' ' (実際に使いたいときはこの部分をコメントアウトして試してみてください。) ' o_PvtTable.AddFields RowFields:=Array("行見出しにしたいアイテムのある列名") ' ' ↑ 行ラベルの設定(1つだけの場合。2段、3段、なら、多分だけど、Array("1段目の列名","2段目の列名","3段目の列名")でやる。Columnも同じだと思う。多分。) ' o_PvtTable.AddDataField o_PvtTable.PivotFields("数値合計したい列名"), "合計結果" ' ' ↑ 「合計結果」という名前で集計する End Function '###################################################################### '指定した名前のワークシートが存在するかどうかのチェックの関数・その2 '存在すればTrueを返し、存在しなければFalseを返します。 'ループを使わない方法=エラーで判別する方法、でやっています。 'ちょっと手抜き版 '###################################################################### Function SheetExistChk(s_WsNm05 As String) On Error GoTo error1: If 1 <= Len(Worksheets.Item(s_WsNm05).Name) Then SheetExistChk = True Else End If Exit Function error1: SheetExistChk = False End Function ' ' |
- 投稿タグ
- Accessの独学, ExcelVBA, Excelの独学, Excel操作の基礎, ビジネスパソコンの基礎, ビジネス一般常識, ピボットテーブル関連